﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using PMSGSC.Common;
using DevExpress.XtraEditors;
using PMSGSC.DAL;
using PMSGSC.BLL;
using DevExpress.XtraEditors.Repository;
using DevExpress.XtraEditors.Controls;
using System.Globalization;
using DevExpress.XtraGrid;
using DevExpress.XtraGrid.Views.Grid;
using DevExpress.XtraGrid.Columns;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Data.Linq;
using DevExpress.Utils.OAuth.Provider;
using DevExpress.XtraRichEdit.Model;
using System.Diagnostics;
using DevExpress.XtraGrid.Views.Grid.ViewInfo;
using DevExpress.XtraGrid.Localization;
using DevExpress.XtraTab;

namespace PMSGSC.App
{
    public partial class frmRound : DevExpress.XtraEditors.XtraForm
    {
        public frmRound(frmMain objMain)
        {
            InitializeComponent();
            roundBindingSource.DataSource = Round_BLL.GetAll(frmMain.ship.Ship_ID);
            employeeBindingSource.DataSource = Employee_BLL.GetAll(frmMain.ship.Ship_ID);
            serviceCodeBindingSource.DataSource = ServiceCode_BLL.GetAll(frmMain.ship.Ship_ID);
            main = objMain;
        }
        frmMain main;
        Round round;
        RoundJob roundJob;
        private void btnNew_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            if (status == Status.Update)
            {
                round = roundBindingSource.AddNew() as Round;
                round.Employee_ID = 6;
                round.TimeUnit = "Day(s)";
                round.CreateDate = DateTime.Now.Date;
                status = Status.New;
            }
            else
            {
                XtraMessageBox.Show("Please save current new Round", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }

        }
        private DateTime NextDue(string Frequency, DateTime LastDone, string TimeUnit)
        {
            int Number = int.Parse(Frequency);
            DateTime dt = LastDone;
            switch (TimeUnit)
            {
                case "Day(s)":
                    dt = dt.AddDays(Number);
                    break;
                case "Week(s)":
                    int NumberDay = Number * 7;
                    dt = dt.AddDays(NumberDay);
                    break;
                case "Month(s)":
                    dt = dt.AddMonths(Number);
                    break;
            }
            return dt;
        }
        private void SetValueBeforeInsert(Round round)
        {
            if (roundCodeTextEdit.ContainsFocus)
                round.RoundCode = roundCodeTextEdit.Text;
            if (titleTextEdit.ContainsFocus)
                round.Title = titleTextEdit.Text;
            if (frequencyTextEdit.ContainsFocus && frequencyTextEdit.Text != "")
                round.Frequency = int.Parse(frequencyTextEdit.Text);
            if (timeUnitComboBoxEdit.ContainsFocus)
                round.TimeUnit = timeUnitComboBoxEdit.Text;
            if (lastDoneDateEdit.ContainsFocus && lastDoneDateEdit.Text != "")
                round.LastDone = lastDoneDateEdit.DateTime.Date;
            if (createDateDateEdit.ContainsFocus)
                round.CreateDate = createDateDateEdit.DateTime;
            if (alarmDayBeforeTextEdit.ContainsFocus && alarmDayBeforeTextEdit.Text != "")
                round.AlarmDayBefore = int.Parse(alarmDayBeforeTextEdit.Text);
            else
                round.AlarmDayBefore = 0;


            if (ucRichEditControl1.isChange)
            {
                round.Detail = ucRichEditControl1.richEditControl1.Text;
                ucRichEditControl1.isChange = false;
            }
        }

        private void btnSaveAll_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            if (round != null)
            {
                if (roundCodeTextEdit.Text == "")
                {
                    XtraMessageBox.Show("RoundCode not exits", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }
                SetValueBeforeInsert(round);
                foreach (Round r in roundBindingSource.Cast<Round>().ToList())
                {
                    if (r.LastDone != null && r.Frequency != null)
                    {
                        r.NextDue = NextDue(r.Frequency.ToString(), r.LastDone.Value, r.TimeUnit);
                    }
                    r.Ship_ID = frmMain.ship.Ship_ID;

                    if (r.Round_ID == 0)
                        Round_BLL.Insert(r);
                    else
                        Round_BLL.Update(r);


                }
                status = Status.Update;
            }

        }

        private void serviceCode_IDGridLookUpEdit_EditValueChanging(object sender, DevExpress.XtraEditors.Controls.ChangingEventArgs e)
        {
            if (null == e.NewValue)
                round.ServiceCode = null;
            else
                round.ServiceCode = BaseDAL.DB.ServiceCodes.Single(n => n.SC_ID == (int)e.NewValue);
        }

        private void employee_IDGridLookUpEdit_EditValueChanging(object sender, DevExpress.XtraEditors.Controls.ChangingEventArgs e)
        {
            if (null == e.NewValue)
                round.Employee = null;
            else
                round.Employee = BaseDAL.DB.Employees.Single(n => n.Employee_ID == (int)e.NewValue);          
        }

        private void xtraTabControl1_SelectedPageChanged(object sender, DevExpress.XtraTab.TabPageChangedEventArgs e)
        {
            LoadJob();
        
        }

        private void LoadJob()
        {
            if (xtraTabControl1.SelectedTabPage.Name == "TabJob")
            {
                if (round != null && round.Round_ID != 0)
                {
                    roundJobBindingSource.DataSource = RoundJob_BLL.GetDataByRoundID(round.Round_ID, false);
                    gridView2.OptionsView.NewItemRowPosition = NewItemRowPosition.Top;
                }
                else
                {
                    gridView2.OptionsView.NewItemRowPosition = NewItemRowPosition.None;
                }
            }
        }

        private void roundBindingSource_CurrentChanged(object sender, EventArgs e)
        {
            if (round != null)
            {
                if (ucRichEditControl1.isChange)
                    round.Detail = ucRichEditControl1.richEditControl1.Text;

                ucRichEditControl1.isChange = false;
            }
            round = roundBindingSource.Current as Round;
            if (round != null)
            {
                LoadJob();
                ucRichEditControl1.richEditControl1.Text = round.Detail;
            }
        }
        Equipment equipment;
        private bool TestAddJob(int id)
        {
            for(int i=0; i<roundJobBindingSource.Cast<RoundJob>().ToList().Count -1; i++)
            {
                if (roundJobBindingSource.Cast<RoundJob>().ToList()[i].Job_ID == id)
                    return false;
            }
            return true;
        }
        private void gridView2_ValidateRow(object sender, DevExpress.XtraGrid.Views.Base.ValidateRowEventArgs e)
        {
            GridView view = jobGridControl.FocusedView as GridView;

            if (Equipment_BLL.GetDataByNumber(roundJob.ComponentCode) == null)
            {
                e.Valid = false;
                view.FocusedColumn = colComponentCode;
                e.ErrorText = "Please enter the Component.";
                view.SetColumnError(colComponentCode, "Component is not empty");
                return;
            }
            view.SetRowCellValue(e.RowHandle, colComponentName, roundJob.ComponentName);
            if (roundJob.Job_ID == 0)
            {
                e.Valid = false;
                view.FocusedColumn = colJobCode;
                e.ErrorText = "Please enter the Job.";
                view.SetColumnError(colJobCode, "Job is not empty");
                return;
            }
            if (RoundJob_BLL.isExits(roundJob))
            {
                e.Valid = false;
                view.FocusedColumn = colJobCode;
                e.ErrorText = "Please enter the Job.";
                view.SetColumnError(colJobCode, "Job is exits");
                return;
            }
            
        }
        private void btnComponent_ButtonClick(object sender, ButtonPressedEventArgs e)
        {
            frmGridComponent component = new frmGridComponent();
            component.ShowDialog();
            GridView view = jobGridControl.FocusedView as GridView;
            if (component.equip != null)
            {
                equipment = component.equip;
                if (view.IsNewItemRow(view.FocusedRowHandle) && view.GetRow(view.FocusedRowHandle) == null)
                {
                    view.AddNewRow();
                }
                view.SetRowCellValue(view.FocusedRowHandle, colComponentCode, component.equip.CodeEquipment);
                view.SetRowCellValue(view.FocusedRowHandle, colComponentName, component.equip.NameEquipment);
                view.SetRowCellValue(view.FocusedRowHandle, colJobCode, "");
                view.SetRowCellValue(view.FocusedRowHandle, colJobDescription, "");
                view.SetRowCellValue(view.FocusedRowHandle, colRevision, "");
                roundJob.Job_ID = 0;
                roundJob.ComponentCode = equipment.CodeEquipment;
                roundJob.ComponentName = equipment.NameEquipment;
            }

        }
        Job job;
        private void btnJob_ButtonClick(object sender, ButtonPressedEventArgs e)
        {
            if (equipment != null)
            {
                frmGridJob gridJob = new frmGridJob(equipment.Equipment_ID);
                gridJob.ShowDialog();
                if (gridJob.Job != null)
                {
                    GridView view = jobGridControl.FocusedView as GridView;
                    if (view.IsNewItemRow(view.FocusedRowHandle) && view.GetRow(view.FocusedRowHandle) == null)
                    {
                        view.AddNewRow();
                    }
                    view.SetRowCellValue(view.FocusedRowHandle, colJobCode, gridJob.Job.JobDescription.CodeJD);
                    view.SetRowCellValue(view.FocusedRowHandle, colJobDescription, gridJob.Job.JobDescription.NameJD);
                    view.SetRowCellValue(view.FocusedRowHandle, colRevision, gridJob.Job.JobDescription.RevisionNumber);
                    roundJob.Job_ID = gridJob.Job.Job_ID;
                }
            }
        }

        private void gridView2_RowUpdated(object sender, DevExpress.XtraGrid.Views.Base.RowObjectEventArgs e)
        {
            SaveDataToDatabase();
        }

        // Khai báo trạng thái mặc định 
        private Status status = Status.Update;
        // Tạo một đối tượng lưu trữ các thông tin trên View ==> truyền xuống các layer bên dưới
        private Maker maker = new Maker();
        //Hiển thị số thứ tự của gridview
        private void gridView1_CustomDrawRowIndicator(object sender, DevExpress.XtraGrid.Views.Grid.RowIndicatorCustomDrawEventArgs e)
        {
            if (e.RowHandle >= 0)
            {
                e.Info.DisplayText = (e.RowHandle + 1).ToString();
            }
        }
        private void SaveDataToDatabase()
        {
            roundJob = roundJobBindingSource.Current as RoundJob;
            if (status == Status.Update)
            {
                if (XtraMessageBox.Show("Do you want to save changes?", "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes)
                {
                    bool result = RoundJob_BLL.Update(roundJob);

                    if (!result)
                        XtraMessageBox.Show("Update Unsuccess !", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    else
                        XtraMessageBox.Show("Update Success !", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);

                }
            }
            if (status == Status.New)
            {
                roundJob.Round = BaseDAL.DB.Rounds.Single(n => n.Round_ID == round.Round_ID);
                roundJob.IsCheck = false;
                bool result = RoundJob_BLL.Insert(roundJob);
                WorkOrder workOrder = WorkOrder_BLL.GetWorkOrderByJobID(roundJob.Job_ID);
                workOrder.Type = 4;
                WorkOrder_BLL.Update(workOrder);
 
                if (!result)
                {
                    XtraMessageBox.Show("Insert Unsuccess!", "Information", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                status = Status.Update;
            }
            roundJobBindingSource.DataSource = RoundJob_BLL.GetDataByRoundID(round.Round_ID, false);
        }
        private void DeleteRoundJob(NavigatorButtonClickEventArgs e)
        {
            DeleteRoundJobFinal();
            e.Handled = true;
        }

        private void DeleteRoundJobFinal()
        {
            if (XtraMessageBox.Show("Are you sure you want to delete a Job?", "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes)
            {
                roundJob = roundJobBindingSource.Current as RoundJob;
                WorkOrder workOrder = WorkOrder_BLL.GetWorkOrderByJobID(roundJob.Job_ID);
                if (!RoundJob_BLL.Delete(roundJob))
                {
                    XtraMessageBox.Show("Can't Delete", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    workOrder.Type = 1;
                    WorkOrder_BLL.Update(workOrder);
                }
                roundJobBindingSource.DataSource = RoundJob_BLL.GetDataByRoundID(round.Round_ID, false);
            }
        }

        // Sự kiện nhân phím delete sảy ra
        private void gridView1_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Delete)
                DeleteRoundJobFinal();
        }
        // Khởi tạo giá trị mặc định của ô cần ràng buộc
        private void gridView1_InitNewRow(object sender, DevExpress.XtraGrid.Views.Grid.InitNewRowEventArgs e)
        {
            status = Status.New;
        }
        // Thông báo lỗi nếu dữ liệu nhập vào không đúng
        private void gridView1_InvalidRowException(object sender, DevExpress.XtraGrid.Views.Base.InvalidRowExceptionEventArgs e)
        {
            if (e.RowHandle == GridControl.NewItemRowHandle)
            {
                e.WindowCaption = "Input Error";
            }
            else
            {
                e.ExceptionMode = DevExpress.XtraEditors.Controls.ExceptionMode.NoAction;
                DialogResult dr = XtraMessageBox.Show(jobGridControl.LookAndFeel, this, e.ErrorText + GridLocalizer.Active.GetLocalizedString(GridStringId.ColumnViewExceptionMessage), e.WindowCaption, MessageBoxButtons.YesNo, MessageBoxIcon.Error);
                if (dr == DialogResult.No)
                {
                    e.ExceptionMode = DevExpress.XtraEditors.Controls.ExceptionMode.Ignore;
                    roundJobBindingSource.DataSource = RoundJob_BLL.GetDataByRoundID(round.Round_ID, true);
                    status = Status.Update;
                }
            }

        }
        private bool flag = false;
        // Đặt lại trạng thái update 
        private void gridView1_CellValueChanged(object sender, DevExpress.XtraGrid.Views.Base.CellValueChangedEventArgs e)
        {
            if (e.RowHandle != GridControl.NewItemRowHandle)
            {
                status = Status.Update;
            }
            if (e.Column.FieldName == "ComponentCode" && flag == false)
            {
                flag = true;
                if (e.Value != null && gridView2.FocusedRowHandle == GridControl.NewItemRowHandle)
                {
                    equipment = Equipment_BLL.GetDataByNumber(gridView2.GetRowCellDisplayText(gridView2.FocusedRowHandle, e.Column));
                    GridView view = jobGridControl.FocusedView as GridView;
                    if (equipment != null)
                    {
                        if (view.IsNewItemRow(view.FocusedRowHandle) && view.GetRow(view.FocusedRowHandle) == null)
                        {
                            view.AddNewRow();
                        }

                        view.SetRowCellValue(view.FocusedRowHandle, colComponentCode, equipment.CodeEquipment);
                        view.SetRowCellValue(view.FocusedRowHandle, colComponentName, equipment.NameEquipment);
                        view.SetRowCellValue(view.FocusedRowHandle, colJobCode, "");
                        view.SetRowCellValue(view.FocusedRowHandle, colJobDescription, "");
                        view.SetRowCellValue(view.FocusedRowHandle, colRevision, "");
                        roundJob.Job_ID = 0;
                        roundJob.ComponentCode = equipment.CodeEquipment;
                        roundJob.ComponentName = equipment.NameEquipment;
                    }
                    else
                    {
                        gridView2.SetColumnError(colComponentCode, "Equipment cannot be empty");
                        view.SetRowCellValue(view.FocusedRowHandle, colComponentName,"");
                        view.SetRowCellValue(view.FocusedRowHandle, colJobCode, "");
                        view.SetRowCellValue(view.FocusedRowHandle, colJobDescription, "");
                        view.SetRowCellValue(view.FocusedRowHandle, colRevision, "");
                    }
                    flag = false;
                }
                if (e.Column.FieldName == "JobCode" && flag == false)
                {
                    flag = true;
                    if (gridView2.FocusedRowHandle == GridControl.NewItemRowHandle && e.Value != null)
                    {
                        job = Job_BLL.GetDataByDesc(gridView2.GetRowCellValue(gridView2.FocusedRowHandle, e.Column).ToString());
                        GridView view = jobGridControl.FocusedView as GridView;
                        if (job != null)
                        {
                            if (view.IsNewItemRow(view.FocusedRowHandle) && view.GetRow(view.FocusedRowHandle) == null)
                            {
                                view.AddNewRow();
                            }

                            view.SetRowCellValue(view.FocusedRowHandle, colJobCode, job.JobDescription.CodeJD);
                            view.SetRowCellValue(view.FocusedRowHandle, colJobDescription, job.JobDescription.NameJD);
                            view.SetRowCellValue(view.FocusedRowHandle, colRevision, job.JobDescription.RevisionNumber);
                            roundJob.Job_ID = job.Job_ID;
                          
                        }
                        else
                        {
                            gridView2.SetColumnError(colJobCode, "Job is not empty");
                            view.SetRowCellValue(view.FocusedRowHandle, colJobDescription, "");
                            view.SetRowCellValue(view.FocusedRowHandle, colRevision, "");
                        }
                    }
                    flag = false;
                }
            }
        }

        private void roundJobBindingSource_CurrentChanged(object sender, EventArgs e)
        {
            roundJob = roundJobBindingSource.Current as RoundJob;
        }

        private void btnRefesh_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            roundBindingSource.DataSource = Round_BLL.GetAll(frmMain.ship.Ship_ID);
        }

        private void btnDelete_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            if (round != null)
            {
                if (XtraMessageBox.Show("Are you sure you want to delete a Round?", "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes)
                {
                    round = roundBindingSource.Current as Round;
                    if (Round_BLL.IsRelationship(round))
                        Round_BLL.Delete(round);
                    else
                        XtraMessageBox.Show("Can't Delete", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);

                    roundBindingSource.DataSource = Round_BLL.GetAll(frmMain.ship.Ship_ID);
                }
                status = Status.Update;
            }
        }
        private void DeleteRound(NavigatorButtonClickEventArgs e)
        {
            if (round != null)
            {
                if (XtraMessageBox.Show("Are you sure you want to delete a Round?", "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes)
                {
                    round = roundBindingSource.Current as Round;
                    if (Round_BLL.IsRelationship(round))
                        Round_BLL.Delete(round);
                    else
                        XtraMessageBox.Show("Can't Delete", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);

                    roundBindingSource.DataSource = Round_BLL.GetAll(frmMain.ship.Ship_ID);
                }
            }
            e.Handled = true;
        }
        private void gridView1_CustomDrawRowIndicator_1(object sender, RowIndicatorCustomDrawEventArgs e)
        {
            if (e.RowHandle >= 0)
            {
                e.Info.DisplayText = (e.RowHandle + 1).ToString();
            }
        }

        private void gridView1_ShowingEditor(object sender, CancelEventArgs e)
        {
            e.Cancel = true;
        }

        private void gridView2_ShowingEditor(object sender, CancelEventArgs e)
        {
            GridView view = sender as GridView;
            if (!view.IsNewItemRow(view.FocusedRowHandle))
            {
                e.Cancel = true;
                btnComponent.HideSelection = true;
            }
        }

        private void btnPrint_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            XtraMessageBox.Show("This function building", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        private void roundGridControl_EmbeddedNavigator_ButtonClick(object sender, NavigatorButtonClickEventArgs e)
        {
            switch (e.Button.ButtonType)
            {
                case NavigatorButtonType.CancelEdit:
                    DeleteRound(e);
                    break;
            }
        }

        private void jobGridControl_EmbeddedNavigator_ButtonClick(object sender, NavigatorButtonClickEventArgs e)
        {

            switch (e.Button.ButtonType)
            {
                case NavigatorButtonType.Remove:
                    DeleteRoundJob(e);
                    break;
            }
        }

        private void btnCreate_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {

            if (XtraMessageBox.Show("Are you sure you want to create a workOrder from Round?", "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes)
            {
                frmProcessBar pb = new frmProcessBar();
                System.Threading.Thread thread = new System.Threading.Thread(new System.Threading.ThreadStart(() =>
                {
                    LoadSkinToForm();
                    pb.ShowDialog();
                }
                ));
                thread.Start();

                WorkOrder workOrder = new WorkOrder();
                workOrder.CreateDate = DateTime.Now.Date;
                int CountJob = WorkOrder_BLL.GetQuantityWorkOrder(frmMain.ship.Ship_ID) + 1;
                workOrder.WorkOrderNumber = "NN" + "/" + GetYear(DateTime.Now.Date.Year) + "/" + CountJob.ToString();
                workOrder.Title = round.RoundCode + "-" + round.Title;
                workOrder.Frequency = round.Frequency;
                workOrder.TimeUnit = round.TimeUnit;
                workOrder.LastDone = round.LastDone;
                workOrder.NextDue = round.NextDue;
                workOrder.AlarmDaybefore = round.AlarmDayBefore;
                workOrder.JobDescription = round.Detail;
                workOrder.RespDescipline_ID = round.Employee_ID;
                workOrder.StatusJob_ID = 1;
                workOrder.SC_ID = round.ServiceCode_ID;
                workOrder.Ship_ID = round.Ship_ID;
                workOrder.IsCheck = false;
                workOrder.Complete = false;
                workOrder.Type = 3;
                workOrder.Round_ID = round.Round_ID;
                workOrder.EmployeeCreate = frmMain.UserLogin.Name;


                bool result = WorkOrder_BLL.Insert(workOrder);
                workOrder = WorkOrder_BLL.GetLastWorkOrder();
                List<WorkOrder> workOrderList = new List<WorkOrder>();
                workOrderList.Add(workOrder);

                frmWorkOrderDeatails workOrderDetails = new frmWorkOrderDeatails(workOrderList, main);
                workOrderDetails.MdiParent = main;
                workOrderDetails.Show();


                if (pb.InvokeRequired)
                    pb.BeginInvoke(new Action(() => pb.Close()));
            }
        }
        private int GetYear(int year)
        {
            return year % 1000;
        }
        private static void LoadSkinToForm()
        {
            DevExpress.Skins.SkinManager.EnableFormSkins();
            DevExpress.UserSkins.BonusSkins.Register();
            DevExpress.UserSkins.OfficeSkins.Register();
            DevExpress.LookAndFeel.DefaultLookAndFeel obj = new DevExpress.LookAndFeel.DefaultLookAndFeel();
            try
            {
                LookAndFeelSettings.Load("LookAndFeelSettings.dat");
            }
            catch
            {
                obj.LookAndFeel.SetSkinStyle("Blue");
            }
        }

        private void frequencyTextEdit_KeyPress(object sender, KeyPressEventArgs e)
        {
            OnlyInputNumberic(e);
        }

        private void alarmDayBeforeTextEdit_KeyPress(object sender, KeyPressEventArgs e)
        {
            OnlyInputNumberic(e);
        }
        private static void OnlyInputNumberic(KeyPressEventArgs e)
        {
            const char Delete = (char)8;
            e.Handled = !Char.IsDigit(e.KeyChar) && e.KeyChar != Delete;
        }

    }
}